package com.ruoyi.mp.service.impl;

import com.ruoyi.common.core.exception.ServiceException;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.db.domain.system.MpCashApply;
import com.ruoyi.db.domain.system.MpClient;
import com.ruoyi.db.domain.system.PcGoldConfig;
import com.ruoyi.db.domain.system.PcSilverConfig;
import com.ruoyi.db.domain.web.MpClientBank;
import com.ruoyi.db.domain.web.MpIncomeRecord;
import com.ruoyi.db.mapper.system.MpCashApplyMapper;
import com.ruoyi.db.mapper.system.MpClientMapper;
import com.ruoyi.db.mapper.system.PcGoldConfigMapper;
import com.ruoyi.db.mapper.system.PcSilverConfigMapper;
import com.ruoyi.db.mapper.web.MpClientAddressMapper;
import com.ruoyi.db.mapper.web.MpClientBankMapper;
import com.ruoyi.db.mapper.web.MpIncomeRecordMapper;
import com.ruoyi.mp.service.IMpCashApplyService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.transaction.Transactional;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 用户申请提现记录Service业务层处理
 * 
 * @author ruoyi
 * @date 2022-07-23
 */
@Service
@Transactional(rollbackOn = Exception.class)
public class MpCashApplyServiceImpl implements IMpCashApplyService
{
    @Autowired
    private MpCashApplyMapper mpCashApplyMapper;

    @Autowired
    private PcGoldConfigMapper pcGoldConfigMapper;
    @Autowired
    private MpClientMapper mpClientMapper;
    @Autowired
    private MpClientBankMapper mpClientBankMapper;
    @Autowired
    private MpIncomeRecordMapper mpIncomeRecordMapper;
    @Autowired
    private PcSilverConfigMapper pcSilverConfigMapper;

    /**
     * 查询用户申请提现记录
     * 
     * @param cashApplyId 用户申请提现记录主键
     * @return 用户申请提现记录
     */
    @Override
    public MpCashApply selectMpCashApplyByCashApplyId(Long cashApplyId)
    {
        return mpCashApplyMapper.selectMpCashApplyByCashApplyId(cashApplyId);
    }

    /**
     * 查询用户申请提现记录列表
     * 
     * @param mpCashApply 用户申请提现记录
     * @return 用户申请提现记录
     */
    @Override
    public List<MpCashApply> selectMpCashApplyList(MpCashApply mpCashApply,MpClient client) throws ParseException {
        if(StringUtils.isNotBlank(mpCashApply.getStartTime())){
            SimpleDateFormat sdfTwo = new SimpleDateFormat("yyyy-MM-");
            Date date = new Date();
            date = sdfTwo.parse(mpCashApply.getStartTime()+"-");
            Calendar a = Calendar.getInstance();
            a.setTime(date);
            a.set(Calendar.DATE, 1);//把日期设置为当月第一天
            a.roll(Calendar.DATE, -1);//日期回滚一天，也就是最后一天
            //当月有多少天
            int maxDate = a.get(Calendar.DATE);

            String startTime = sdfTwo.format(date) + "01 00:00:00";
            String endTime = sdfTwo.format(date) + maxDate + " 23:59:59";
            mpCashApply.setStartTime(startTime);
            mpCashApply.setEndTime(endTime);
        }
        List<MpCashApply> list =  mpCashApplyMapper.selectMpCashApplyList(mpCashApply);;
        for (MpCashApply apply: list) {
            Long clientBankId = apply.getClientBankId();
            MpClientBank bank = mpClientBankMapper.selectMpClientBankById(clientBankId);
            if(bank!=null){
                apply.setBankAccountName(bank.getBankAccountName());
            }
        }
        return list;
    }

    /**
     * 新增用户申请提现记录
     * 
     * @param mpCashApply 用户申请提现记录
     * @return 结果
     */
    @Override
    public void insertMpCashApply(MpCashApply mpCashApply, MpClient client)
    {

        PcGoldConfig pcGoldConfig = new PcGoldConfig();
        List<PcGoldConfig> configs = pcGoldConfigMapper.selectPcGoldConfigList(pcGoldConfig);
        if(configs.size()>0){
            PcGoldConfig config = configs.get(0);
            if(config!=null&&config.getCashApply().equals("0")){
                throw new ServiceException("系统暂时不能提现");
            }
        }

        LocalDateTime todayStart = null;
        LocalDateTime todayEnd = null;
        Long  day = null;
        Long endDay = null;
        int monthDay = LocalDateTime.now().getDayOfMonth()-1;
        day = Long.valueOf(-monthDay);
        Calendar aCalendar = Calendar.getInstance(Locale.CHINA);
        endDay = Long.valueOf(aCalendar.getActualMaximum(Calendar.DATE)- LocalDateTime.now().getDayOfMonth());
        todayStart = LocalDateTime.of(LocalDate.now().plusDays(day), LocalTime.MIN);//当天零点
        todayEnd = LocalDateTime.of(LocalDate.now().plusDays(endDay), LocalTime.MAX);//当天零点
        String startTimeM= todayStart.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        String endTimeM= todayEnd.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        //获取当前提现银行卡账户
        MpClientBank mpClientBank = mpClientBankMapper.selectMpClientBankById(mpCashApply.getClientBankId());
        MpClientBank sBank = new MpClientBank();
        sBank.setIdNumber(mpClientBank.getIdNumber());
        sBank.setClientId(mpClientBank.getClientId());
        List<MpClientBank> myBank = mpClientBankMapper.selectMpClientBankList(sBank);

        MpCashApply mpCashApplyOldM = new MpCashApply();
        mpCashApplyOldM.setClientId(mpCashApply.getClientId());
        mpCashApplyOldM.setStartTime(startTimeM);
        mpCashApplyOldM.setEndTime(endTimeM);
        List<MpCashApply> oldListM = mpCashApplyMapper.selectMpCashApplyListByTime(mpCashApplyOldM);
        BigDecimal cashSumM = oldListM.stream().filter(e->!myBank.contains(e.getClientBankId())).map( MpCashApply::getApplyAmount ).reduce(BigDecimal.ZERO, BigDecimal::add); //BigDecimal类型
        BigDecimal cashTodayM = cashSumM.add(mpCashApply.getApplyAmount());
        if(cashTodayM.compareTo(new BigDecimal("145000"))>0){
            throw new ServiceException("本月提现额度已达上限");
        }
        if(configs.size()>0){
            PcGoldConfig config = configs.get(0);
            BigDecimal cashLimit = config.getCashLimit();

            MpCashApply mpCashApplyOld = new MpCashApply();
            mpCashApplyOld.setClientId(mpCashApply.getClientId());
            String startTime = getTodayStartTime();
            String endTime = getTodayEndTime();
            mpCashApplyOld.setStartTime(startTime);
            mpCashApplyOld.setEndTime(endTime);
            List<MpCashApply> oldList = mpCashApplyMapper.selectMpCashApplyListByTime(mpCashApplyOld);
            BigDecimal cashSum = oldList.stream().map( MpCashApply::getApplyAmount ).reduce(BigDecimal.ZERO, BigDecimal::add); //BigDecimal类型
            BigDecimal cashToday = cashSum.add(mpCashApply.getApplyAmount());
            if(cashToday.compareTo(cashLimit)>0){
                throw new ServiceException("今日提现额度已达上限");
            }
        }
        if(mpCashApply.getType()==1){
            BigDecimal goldRate =configs.get(0).getCashRate();
            BigDecimal taxRate = configs.get(0).getTaxRate();
            BigDecimal totalAmount = mpCashApply.getApplyAmount().multiply(goldRate.add(new BigDecimal("1")).add(taxRate));
            if(client.getGoldBeanBalance().compareTo(totalAmount)<0){
                throw new ServiceException("用户可用金藻不足");
            }
            mpCashApply.setClientId(client.getClientId());
            mpCashApply.setApplyTime(new Date());
            mpCashApply.setApprovalStatus("101");
            mpCashApply.setGoldCashAmount(goldRate.multiply(mpCashApply.getApplyAmount()));
            mpCashApply.setTaxAmount(taxRate.multiply(mpCashApply.getApplyAmount()));
            if(mpCashApplyMapper.insertMpCashApply(mpCashApply)>0){
                client.setGoldBeanBalance(client.getGoldBeanBalance().subtract(totalAmount));
                mpClientMapper.updateMpClient(client);
                MpIncomeRecord recordReturn = new MpIncomeRecord();
                recordReturn.setClientId(client.getClientId());
                recordReturn.setCreateTime(new Date());
                recordReturn.setIsIncome(0l);
                recordReturn.setAmount(totalAmount);
                recordReturn.setContent("用户提现及手续费");
                recordReturn.setType(1l);
                recordReturn.setCurrentBalance(client.getGoldBeanBalance());
                mpIncomeRecordMapper.insertMpIncomeRecord(recordReturn);
            }
        }
        if(mpCashApply.getType()==2){
            PcSilverConfig silverConfig = new PcSilverConfig();
            List<PcSilverConfig> silverConfigs = pcSilverConfigMapper.selectPcSilverConfigList(silverConfig);
            BigDecimal silverRate = silverConfigs.get(0).getCashReplaceRate();
            BigDecimal goldRate =configs.get(0).getCashRate().multiply(silverRate);
            BigDecimal taxRate = configs.get(0).getTaxRate();
            BigDecimal totalGoldAmount = mpCashApply.getApplyAmount().multiply((new BigDecimal("1")).add(taxRate));
            BigDecimal totalSilverAmount = mpCashApply.getApplyAmount().multiply(goldRate);
            if(client.getSilverBeanBalance().compareTo(totalSilverAmount)<0){
                throw new ServiceException("用户可用银藻不足");
            }
            if(client.getGoldBeanBalance().compareTo(totalGoldAmount)<0){
                throw new ServiceException("用户可用金藻不足");
            }
            mpCashApply.setClientId(client.getClientId());
            mpCashApply.setApplyTime(new Date());
            mpCashApply.setApprovalStatus("101");
            mpCashApply.setTaxAmount(taxRate.multiply(mpCashApply.getApplyAmount()));
            mpCashApply.setSilverCashAmount(totalSilverAmount);
            if(mpCashApplyMapper.insertMpCashApply(mpCashApply)>0){
                client.setSilverBeanBalance(client.getSilverBeanBalance().subtract(totalSilverAmount));
                client.setGoldBeanBalance(client.getGoldBeanBalance().subtract(totalGoldAmount));
                mpClientMapper.updateMpClient(client);
                MpIncomeRecord recordReturn = new MpIncomeRecord();
                recordReturn.setClientId(client.getClientId());
                recordReturn.setCreateTime(new Date());
                recordReturn.setIsIncome(0l);
                recordReturn.setAmount(totalGoldAmount);
                recordReturn.setContent("用户提现及手续费");
                recordReturn.setType(1l);
                recordReturn.setCurrentBalance(client.getGoldBeanBalance());
                mpIncomeRecordMapper.insertMpIncomeRecord(recordReturn);
                MpIncomeRecord recordReturn1 = new MpIncomeRecord();
                recordReturn1.setClientId(client.getClientId());
                recordReturn1.setCreateTime(new Date());
                recordReturn1.setIsIncome(0l);
                recordReturn1.setAmount(totalSilverAmount);
                recordReturn1.setContent("用户提现银藻手续费");
                recordReturn1.setType(2l);
                recordReturn1.setCurrentBalance(client.getSilverBeanBalance());
                mpIncomeRecordMapper.insertMpIncomeRecord(recordReturn1);
            }
        }

    }

    @Override
    public Map<String, Object> getMpCashApply() {
        Map<String,Object> map = new HashMap<>();
        List<PcGoldConfig> goldConfigs = pcGoldConfigMapper.selectPcGoldConfigList(new PcGoldConfig());
        map.put("goldRate",goldConfigs.get(0).getCashRate());
        map.put("taxRate",goldConfigs.get(0).getTaxRate());
        List<PcSilverConfig> silverConfigs = pcSilverConfigMapper.selectPcSilverConfigList(new PcSilverConfig());
        map.put("silverRate",goldConfigs.get(0).getCashRate().multiply(silverConfigs.get(0).getCashReplaceRate()));
        return map;
    }

    public String getTodayStartTime(){
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String todayStartTime=sdf.format(new Date());
        return  todayStartTime;
    }
    public String getTodayEndTime(){
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Calendar todayCalendar = Calendar.getInstance();
        todayCalendar.add(Calendar.DATE,1); // 获取明天00:00:00
        //今天结束时间
        Date end = todayCalendar.getTime();
        String todayEndTime=sdf.format(end);
        return todayEndTime;
    }
}
